﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

using Microsoft.SolverFoundation.Services;

namespace Flux_Balance_Analysis
{
    /// <summary>
    /// Logica di interazione per ReactionWindow.xaml
    /// </summary>
    public partial class ReactionWindow : Window
    {
        public Reaction Reaction { get; private set; }

        Metabolite source, dest, 
             oldSource, oldDest;
        string name;

        //public ReactionWindow()
        //{
        //    InitializeComponent();
        //}

        public ReactionWindow(Reaction reaction)
        {
            InitializeComponent();

            if (reaction != null)
            {
                this.Reaction = reaction;
                oldSource = reaction.Source as Metabolite;
                oldDest = reaction.Target as Metabolite;
                cmdDelete.Visibility = System.Windows.Visibility.Visible;
            }
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            foreach (Metabolite metabolite in FBACore.Metabolites)
            {
                cmbSource.Items.Add(metabolite.Name);
            }
            if (this.Reaction != null)
            {
                this.Title = this.name = this.Reaction.Name;

                cmbSource.SelectedItem = this.Reaction.Source.Name;
                cmbDest.SelectedItem = this.Reaction.Target.Name;
            }
        }

        private void cmbSource_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            // TODO: Controllare se è possibile effettuare più reazioni con gli stessi metaboliti!
            // Pulisco la lista dei metaboliti a cui è possibile connettersi
            cmbDest.Items.Clear();

            // Se ho selezionato un oggetto valido
            if (cmbSource.SelectedItem != null)
            {
                // Cerco il metabolita che ha il nome selezionato
                source = FBACore.Metabolites.FirstOrDefault(m => m.Name == cmbSource.SelectedItem.ToString());

                if (this.Reaction == null)
                {
                    if (source.IsExternal)
                        name = "B" + FBACore.ExternalFluxes;
                    else
                        name = "V" + FBACore.InternalFluxes;

                    this.Title = "Reazione: " + name;
                }
                // Se lo trovo
                if (source != null)
                {
                    // Ottengo tutte le reazioni che partono da lui
                    IEnumerable<Reaction> reactions = FBACore.Reactions.Where(r => r.Source == source);

                    // Scorro tutti i metaboliti inseriti nel sistema
                    foreach (Metabolite metabolita in FBACore.Metabolites)
                    {
                        // TODO: posso collegare due metaboliti esterni? io non credo...
                        // Ogni metabolita che non è già raggiunto da source è una possibile destinazione
                        if (metabolita != source && reactions.Count(r => r.Target == metabolita && r.Target != oldDest) <= 0 && (!metabolita.IsExternal || !source.IsExternal))
                        {
                            // quindi lo inserisco nei candidati al collegamento
                            cmbDest.Items.Add(metabolita.Name);
                        }
                    }
                }
            }
        }

        private void cmdCancel_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
            this.Close();
        }

        private void cmdConfirm_Click(object sender, RoutedEventArgs e)
        {
            // determino la scelta del nome: V flusso interno, B flusso esterno
            if (cmbSource.SelectedItem != null && cmbDest.SelectedItem != null)
            {
                // Creo la reazione
                if(source != oldSource || dest != oldDest)
                    this.Reaction = new Reaction(name, source, dest);

                this.DialogResult = true;
                this.Close();
            }
        }

        private void cmbDest_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (cmbDest.SelectedItem != null)
            {
                dest = FBACore.Metabolites.FirstOrDefault(m => m.Name == cmbDest.SelectedItem.ToString());

                if (this.Reaction == null)
                {
                    if (source.IsExternal || dest.IsExternal)
                        name = "B" + FBACore.ExternalFluxes;
                    else
                        name = "V" + FBACore.InternalFluxes;
                    this.Title = "Reazione: " + name;
                }
            }
        }

        private void cmdDelete_Click(object sender, RoutedEventArgs e)
        {
            this.Reaction = null;
            this.DialogResult = true;
            this.Close();
        }
    }
}
